package cn.green.core.scanner;

import cn.green.core.components.field.*;
import cn.green.core.components.store.field.*;
import cn.green.core.components.store.table.TableTypeStore;
import cn.green.core.components.table.TableTypeCom;
import cn.green.core.scanner.anno.EnableQTableScan;
import cn.green.core.scanner.anno.comps.QTableComponent;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ClassUtils;

import java.util.*;

/**
 * @author wang.yishu
 * @version 1.0
 * @className QTableComponentScanner
 * @description 动态表组件扫描器
 * @date 2024/11/18 13:54
 */
public class QTableComponentScanner implements ImportSelector {

    public static final String BASE_PACKAGE = "cn.green";

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        List<String> allComponentsName = new ArrayList<>();
        ClassPathScanningCandidateComponentProvider provider =
                new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AnnotationTypeFilter(QTableComponent.class));

        // 获取扫描结果的全限定类名
        List<String> componentNames = new ArrayList<>();
        // 扫描指定包，如果有多个包，这个过程可以执行多次
        String[] packages = getPackageToScan(annotationMetadata);
        for (String aPackage : packages) {
            Set<BeanDefinition> beanDefinitionSet = provider.findCandidateComponents(aPackage);
            beanDefinitionSet.forEach(beanDefinition -> componentNames.add(beanDefinition.getBeanClassName()));
        }
        for (String componentClass : componentNames) {
            try {
                Class<?> aClass = Class.forName(componentClass);
                if (FieldTypeCom.class.isAssignableFrom(aClass)) {
                    FieldTypeCom fieldTypeCom = (FieldTypeCom) aClass.newInstance();
                    FieldTypeStore.put(fieldTypeCom);
                } else if (FieldFormTypeCom.class.isAssignableFrom(aClass)) {
                    FieldFormTypeCom fieldFormTypeCom = (FieldFormTypeCom) aClass.newInstance();
                    FieldFormTypeStore.put(fieldFormTypeCom);
                } else if (FieldCheckTypeCom.class.isAssignableFrom(aClass)) {
                    FieldCheckTypeCom fieldCheckTypeCom = (FieldCheckTypeCom) aClass.newInstance();
                    FieldCheckTypeStore.put(fieldCheckTypeCom);
                } else if (FieldAuthTypeCom.class.isAssignableFrom(aClass)) {
                    FieldAuthTypeCom fieldAuthTypeCom = (FieldAuthTypeCom) aClass.newInstance();
                    FieldAuthTypeStore.put(fieldAuthTypeCom);
                } else if (FieldUnitTypeCom.class.isAssignableFrom(aClass)) {
                    FieldUnitTypeCom fieldUnitTypeCom = (FieldUnitTypeCom) aClass.newInstance();
                    FieldUnitTypeStore.put(fieldUnitTypeCom);
                } else if (DefaultTypeCom.class.isAssignableFrom(aClass)) {
                    DefaultTypeCom defaultTypeCom = (DefaultTypeCom) aClass.newInstance();
                    DefaultValueTypeStore.put(defaultTypeCom);
                } else if (TableTypeCom.class.isAssignableFrom(aClass)) {
                    TableTypeCom tableTypeCom = (TableTypeCom) aClass.newInstance();
                    TableTypeStore.put(tableTypeCom);
                }
                allComponentsName.add(componentClass);
                System.out.println("QTable! -> load component : " + componentClass);
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return allComponentsName.toArray(new String[0]);
    }

    private String[] getPackageToScan(AnnotationMetadata metadata) {
        //通过自定义注解获取自定义包路径
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(EnableQTableScan.class.getName()));
        if (attributes == null) {
            return new String[]{BASE_PACKAGE};
        }
        String[] basePackages = attributes.getStringArray("basePackages");
        if (basePackages.length != 0) {
            Set<String> rtnSet = new HashSet<>(Arrays.asList(basePackages));
            rtnSet.add(BASE_PACKAGE);
            return rtnSet.toArray(new String[1]);
        }
        return new String[]{ClassUtils.getPackageName(metadata.getClassName())};
    }
}
